package com.tarena.csmall.sso.service;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.pojo.sso.authentication.CsmallAuthenticationInfo;
import cn.tedu.mall.common.pojo.ums.model.User;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.common.utils.JwtTokenUtils;
import com.tarena.csmall.sso.mapper.UserMapper;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.jacoco.agent.rt.internal_035b120.core.internal.flow.IFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class IPhoneService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    public void sendCode(String phone) {
        //验证一下正则
        checkPhoneNum(phone);
        //生成短信验证码
        String code = generateCode(phone);
        //发送短信
        send(phone,code);
    }

    private void send(String phone, String code) {
        log.info("当前手机号:{},收到验证码:{}",phone,code);
    }

    private String generateCode(String phone) {
        /**
         * 设置检验5分钟超过3次的验证码发送限制逻辑
         */
        String lock_key = "mall:sso:sms:lock:" + phone;
        String code_key = "mall:sso:sms:code:" + phone;
        String check_key = "mall:sso:sms:check:" + phone;
        Long now = new Date().getTime();
        String code = new Random().nextInt(899999) + 100000 + "";
        //判断有没有锁
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        ListOperations<String, String> opsForList = redisTemplate.opsForList();
        if (redisTemplate.hasKey(lock_key)) {//exist
            throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST, "当前手机号已经被锁住,请10分钟之后重试");
        }
        //获取集合
        Long size = opsForList.size(check_key);
        if (size == 3){
            //拿到最早的时间戳
            String s = opsForList.rightPop(check_key);
            Long first=Long.parseLong(s);
            //检验相隔时间
            Long gap=now-first;
            if (gap<1000*60*5){
                //清空所有内容
                redisTemplate.delete(code_key);
                redisTemplate.delete(check_key);
                //保存锁
                opsForValue.set(lock_key,"",10,TimeUnit.MINUTES);
                throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST,"您的手机号5分钟之内超过3次发送验证码,锁定10分钟,请10分钟之后重试");
            }
        }
        //把当前时间戳存放到list中
        opsForList.leftPush(check_key,now+"");
        //存储code到redis保存10分钟
        opsForValue.set(code_key,code,10, TimeUnit.MINUTES);
        return code;
    }

    private void checkPhoneNum(String phone) {
        String regexStr = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
        if (phone == null || !phone.matches(regexStr)) {
            throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST, "电话号码不符合规范");
        }
    }
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;
    public String loginWithCode(String phone, String code) {
        //先对比验证码
        String code_key = "mall:sso:sms:code:" + phone;
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        String codeStore = opsForValue.get(code_key);
        if (code == null || codeStore == null || !code.equals(codeStore)){
            throw new CoolSharkServiceException(ResponseCode.CONFLICT,"验证码有问题,请联系管理员");
        }else {
            //生成jwt 根据用户信息
            //查询用户对象,有则使用,没有则创建新的 使用电话号码
            User user=userMapper.selectUserByPhone(phone);
            if (user ==null){
                //存储登录用户
                user=new User();
                user.setUsername(phone);
                user.setEmail(phone);//默认email不能相同,mysql有
                user.setPhone(phone);
                userMapper.save(user);
            }
            //创建CsmallUserInfo
            CsmallAuthenticationInfo userInfo=new CsmallAuthenticationInfo();
            userInfo.setId(user.getId());
            userInfo.setUserType("USER");
            List<String> authorities=new ArrayList<>();
            authorities.add("ROLE_user");
            userInfo.setAuthorities(authorities);
            return jwtTokenUtils.generateToken(userInfo);
        }

    }
}
